package com.factory._07decorator;

/**
 * 装饰器模式：
 * （1）Component（抽象构建）：这里指的奶茶抽象接口，表示规范准备接收附加责任的对象。
 * 定义奶茶接口
 * <p>
 * （2）ConcreteComponent（具体构建）：这里指珍珠奶茶、蜂蜜奶茶等具体的奶茶。
 * <p>
 * （3）Decorator（装饰器）：定义一个与抽象构件接口一致的接口，这里表示各种口味。
 * <p>
 * （4）ConcreteDecorator（具体装饰器）：具体不同的口味，给奶茶一些附加的特色。
 * step：
 * 第一步：定义奶茶接口（Component）
 * 第二步：定义两种不同种类的奶茶：珍珠奶茶和蜂蜜奶茶（ConcreteComponent）
 * 第三步：定义口味（Decorator）
 * 第四步：具体口味（ConcreteDecorator）：加冰和加咖啡
 * <p>
 * 2、装饰器模式与适配器模式区别
 * （1）概念区分
 * <p>
 * 适配器模式，一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起，做法是将类自己的接口包裹在一个已存在的类中。
 * <p>
 * 装饰器模式，原有的不能满足现有的需求，对原有的进行增强。
 * <p>
 * （2）继承特点
 * <p>
 * 适配器模式是用新接口来调用原接口，原接口对新系统是不可见或者说不可用的。
 * <p>
 * 装饰者模式原封不动的使用原接口，系统对装饰的对象也通过原接口来完成使用。（增加新接口的装饰者模式可以认为是其变种--“半透明”装饰者）
 * <p>
 * （3）包装
 * <p>
 * 装饰模式包装的是自己的兄弟类，隶属于同一个家族（相同接口或父类），
 * <p>
 * 适配器模式则修饰非血缘关系类，把一个非本家族的对象伪装成本家族的对象，注意是伪装，因此它的本质还是非相同接口的对象。
 *
 * @author Qinye
 * @date 2023/8/11 23:16
 */
public class Test {
    public static void main(String[] args) {
        MilkTea milkTea = new HoneyMilkTea();
        System.out.println("买了一杯蜂蜜奶茶，价格是 " + milkTea.milkTeaPrice());
        milkTea = new AddIceTaste(milkTea);
        System.out.println("加冰，价格是 " + milkTea.milkTeaPrice());
        milkTea = new AddCoffeTaste(milkTea);
        System.out.println("加咖啡，价格是 " + milkTea.milkTeaPrice());


        System.out.println("--------------------------");


        MilkTea milkTea2 = new PearMilkTea();
        System.out.println("买了一杯珍珠奶茶，价格是 " + milkTea2.milkTeaPrice());
        milkTea2 = new AddIceTaste(milkTea2);
        System.out.println("加冰，价格是 " + milkTea2.milkTeaPrice());
        milkTea2 = new AddCoffeTaste(milkTea2);
        System.out.println("加咖啡，价格是 " + milkTea2.milkTeaPrice());


    }
}
